package com.ildepinc.persistence.concretes;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;

import com.ildepinc.persistence.abstracts.DaoTableGeneric;
import com.ildepinc.persistence.concretes.daos.DaoCatalog;
import com.ildepinc.persistence.concretes.models.Catalog;

@TestMethodOrder(OrderAnnotation.class)
class DaoCatalogTest {

  private static Persistence persistenceLayer;
  private DaoCatalog daoCatalog;

  @BeforeAll
  static void setUpBeforeClass() throws Exception {
    persistenceLayer = new Persistence();
  }

  @Test
  @Order(1)
  void testStartLayer() {
    assertTrue(persistenceLayer.startLayer());
  }

  @Test
  @Order(2)
  void testManualDeleteTableGeneric() {
    this.daoCatalog = (DaoCatalog) persistenceLayer.getDaoTableGenericMap().get("DaoCatalog");
    assertTrue(this.daoCatalog instanceof DaoTableGeneric);
    String deleteSql = this.daoCatalog.getTable().getSqlDelete();
    this.daoCatalog.setSqlCommand(deleteSql);
    ArrayList<Object> sqlParameters = new ArrayList<Object>();
    sqlParameters.add(2L);
    this.daoCatalog.setSqlParameters(sqlParameters);
    Integer rowsAffected = 0;
    try {
      rowsAffected = this.daoCatalog.doManualDmlOrDdl();
    } catch (Exception e) {
      e.printStackTrace();
    }
    assertTrue((rowsAffected == 0) || (rowsAffected == 1));
  }

  @Test
  @Order(3)
  void testDeleteTableGeneric() {
    this.daoCatalog = (DaoCatalog) persistenceLayer.getDaoTableGenericMap().get("DaoCatalog");
    assertTrue(this.daoCatalog instanceof DaoTableGeneric);
    Integer rowsAffected = null;
    HashMap<String, Object> primaryKeys = new HashMap<String, Object>();
    primaryKeys.put("ID", 1L);
    try {
      rowsAffected = this.daoCatalog.doDelete(primaryKeys);
    } catch (Exception e) {
      e.printStackTrace();
    }
    assertTrue((rowsAffected == 0) || (rowsAffected == 1));
  }

  @Test
  @Order(4)
  void testInsertTableGeneric() {
    this.daoCatalog = (DaoCatalog) persistenceLayer.getDaoTableGenericMap().get("DaoCatalog");
    assertTrue(this.daoCatalog instanceof DaoTableGeneric);
    Integer rowsAffected = null;
    Catalog catalog = new Catalog(null, "LANGUAGE", "Languages", "devschema");
    this.daoCatalog.setTable(catalog);
    try {
      rowsAffected = this.daoCatalog.doInsert(catalog, null);
    } catch (Exception e) {
      e.printStackTrace();
    }
    assertEquals(1, rowsAffected);
  }

  @Test
  @Order(5)
  void testUpdateTableGeneric() {
    this.daoCatalog = (DaoCatalog) persistenceLayer.getDaoTableGenericMap().get("DaoCatalog");
    assertTrue(this.daoCatalog instanceof DaoTableGeneric);
    Integer rowsAffected = null;
    Catalog catalog = new Catalog(1L, "LANGUAGE", "Languages", "devschema");
    this.daoCatalog.setTable(catalog);
    try {
      rowsAffected = this.daoCatalog.doUpdate(catalog);
    } catch (Exception e) {
      e.printStackTrace();
    }
    assertEquals(1, rowsAffected);
  }

  @Test
  @Order(6)
  void testSelectTableGeneric() {
    this.daoCatalog = (DaoCatalog) persistenceLayer.getDaoTableGenericMap().get("DaoCatalog");
    assertTrue(this.daoCatalog instanceof DaoTableGeneric);
    Catalog catalog = null;
    HashMap<String, Object> primaryKeys = new HashMap<String, Object>();
    primaryKeys.put("ID", 1L);
    try {
      catalog = (Catalog) this.daoCatalog.doSelect(primaryKeys);
    } catch (Exception e) {
      e.printStackTrace();
    }
    assertEquals(1L, catalog.getId());
  }

  @Test
  @Order(7)
  void testManualInsertTableGeneric() {
    this.daoCatalog = (DaoCatalog) persistenceLayer.getDaoTableGenericMap().get("DaoCatalog");
    assertTrue(this.daoCatalog instanceof DaoTableGeneric);
    String insertSql = this.daoCatalog.getTable().getSqlInsert();
    this.daoCatalog.setSqlCommand(insertSql);
    ArrayList<Object> sqlParameters = new ArrayList<Object>();
    sqlParameters.add(2L);
    sqlParameters.add("COUNTRY");
    sqlParameters.add("Countries");
    this.daoCatalog.setSqlParameters(sqlParameters);
    Integer rowsAffected = 0;
    try {
      rowsAffected = this.daoCatalog.doManualDmlOrDdl();
    } catch (Exception e) {
      e.printStackTrace();
    }
    assertEquals(1, rowsAffected);
  }

  @Test
  @Order(8)
  void testManualUpdateTableGeneric() {
    this.daoCatalog = (DaoCatalog) persistenceLayer.getDaoTableGenericMap().get("DaoCatalog");
    assertTrue(this.daoCatalog instanceof DaoTableGeneric);
    String updateSql = this.daoCatalog.getTable().getSqlUpdate();
    this.daoCatalog.setSqlCommand(updateSql);
    ArrayList<Object> sqlParameters = new ArrayList<Object>();
    sqlParameters.add("COUNTRY");
    sqlParameters.add("Countries");
    sqlParameters.add(2L);
    this.daoCatalog.setSqlParameters(sqlParameters);
    Integer rowsAffected = 0;
    try {
      rowsAffected = this.daoCatalog.doManualDmlOrDdl();
    } catch (Exception e) {
      e.printStackTrace();
    }
    assertEquals(1, rowsAffected);
  }

  @Test
  @Order(9)
  void testManualSelectTableGeneric() {
    this.daoCatalog = (DaoCatalog) persistenceLayer.getDaoTableGenericMap().get("DaoCatalog");
    assertTrue(this.daoCatalog instanceof DaoTableGeneric);
    String selectSql = this.daoCatalog.getTable().getSqlSelect();
    this.daoCatalog.setSqlCommand(selectSql);
    ArrayList<Object> sqlParameters = new ArrayList<Object>();
    sqlParameters.add(2L);
    this.daoCatalog.setSqlParameters(sqlParameters);
    ResultSet resultSet = null;
    Long retriviedId = 0L;
    try {
      resultSet = this.daoCatalog.doManualSelect();
      resultSet.first();
      retriviedId = resultSet.getLong(1);
    } catch (Exception e) {
      e.printStackTrace();
    }
    assertEquals(2L, retriviedId);
  }

  @Test
  @Order(10)
  void testStopLayer() {
    assertTrue(persistenceLayer.stopLayer());
  }

  @AfterAll
  static void tearDownAfterClass() throws Exception {
    persistenceLayer = null;
  }

}
